package webserver;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.StringTokenizer;

class HttpRequest implements Runnable
{
	final static String CRLF = "\r\n";
	Socket socket;
	// Constructor
	public HttpRequest(Socket socket) throws Exception
	{
		this.socket = socket;
	}
	// Implement the run() method of the Runnable interface.
	public void run()
	{
		try {
			processRequest();
		} catch (Exception e) {
			System.out.println(e);
		}

	}
	private void processRequest() throws Exception
	{
		// Get a reference to the socket's input and output streams.
		InputStreamReader is = new InputStreamReader(socket.getInputStream());
		DataOutputStream os = new DataOutputStream(socket.getOutputStream());
		// Set up input stream filters.
		
		BufferedReader br = new BufferedReader(is);
		
		// Get the request line of the HTTP request message.
		String requestLine = br.readLine();
		// Display the request line.
		System.out.println("\nNew Request Received : ----");
		System.out.println(requestLine);
		
		// Get and display the header lines.
		String headerLine = null;
		while ((headerLine = br.readLine()).length() != 0) {
		        System.out.println(headerLine);
		}
		
		StringTokenizer tokens = new StringTokenizer(requestLine);
		tokens.nextToken();
		String fileName = "." + tokens.nextToken();
		
		FileInputStream fis = null;
		boolean fileExists = true;
		
		try {
			fis = new FileInputStream(fileName);
		}
		catch (FileNotFoundException e){
			fileExists = false;
		}
		
		// construct responce message
		
		String statusLine = null;
		String contentTypeLine  = null;
		String entityBody = null;
		
		if(fileExists){
			statusLine = "HTTP/1.1 200 OK\n" ;
			contentTypeLine = "Content-type: " + contentType(fileName) + CRLF;
		}
		
		else{
			statusLine= "HTTP/1.1 404 Not Found \n ";
			contentTypeLine =  "Content-type: text/html " + CRLF;
			entityBody = "<HTML><HEAD><TITLE>404 Not Found</TITLE> " +
					"</HEAD> <BODY>Sad Monkey :( - Page Not Found." +
					"<br />Did you enter the correct address?</BODY></HTML>";		
			
		}
		
		 // send status line
		os.writeBytes(statusLine);
		
		// send content type line
		os.writeBytes(contentTypeLine);
		
		// crlf
		os.writeBytes(CRLF);
		
		// send entity body
		if(fileExists){
			sendBytes(fis, os);
			fis.close();
		}
		else{
			os.writeBytes(entityBody);
		}
		
		
		
		// Close streams and socket.
		os.close();
		br.close();
		socket.close();

	}
	
	private static void sendBytes(FileInputStream fis, OutputStream os) throws Exception{
		byte[] buffer = new byte[1024];
		int bytes= 0;
		
		while((bytes = fis.read(buffer))!=-1 ){
			os.write(buffer, 0,bytes);
		}
	}
	
	
	private static String contentType(String fileName){
		if (fileName.endsWith(".htm")|| fileName.endsWith(".html")){
			return "text/html";
			
		}
		if (fileName.endsWith(".jpg")|| fileName.endsWith(".jpeg")){
			return "image/jpeg";
			
		}
		if (fileName.endsWith(".gif")){
			return "image/gif";
			
		}
		if (fileName.endsWith(".png")){
			return "image/png";
			
		}
		if (fileName.endsWith(".mp4")|| fileName.endsWith(".mpeg4")){
			return "video/mp4";
			
		}
		if (fileName.endsWith(".mpg")|| fileName.endsWith(".mpeg")){
			return "video/mpeg";
			
		}
		if (fileName.endsWith(".pdf")){
			return "application/pdf";
			
		}
		
		
		return "application/octet-stream";
		}
	}